package cn.chiship.sdk.third.storage.impl;

import cn.chiship.sdk.core.base.BaseResult;
import cn.chiship.sdk.core.util.StringUtil;
import cn.chiship.sdk.third.core.model.ali.AliOssConfigModel;
import cn.chiship.sdk.third.storage.FileStorageService;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.DeleteObjectsRequest;
import com.aliyun.oss.model.DeleteObjectsResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.*;

/**
 * 阿里云存储实现类
 *
 * @author lj
 */
public class AliOssServiceImpl implements FileStorageService {

    private static final Logger LOGGER = LoggerFactory.getLogger(AliOssServiceImpl.class);

    private static final String S1 = "AliOssServiceImpl发生错误:{}";

    private AliOssConfigModel aliOssConfigModel;

    public AliOssServiceImpl(AliOssConfigModel aliOssConfigModel) {
        this.aliOssConfigModel = aliOssConfigModel;
    }

    public AliOssServiceImpl() {
        this.aliOssConfigModel = new AliOssConfigModel();
    }

    @Override
    public BaseResult upload(InputStream inputStream, String fileName) {
        return upload(inputStream, null, fileName);
    }

    @Override
    public BaseResult upload(InputStream inputStream, String catalog, String fileName) {
        try {
            String fileUrl = String.format("http://%s.%s/%s/", aliOssConfigModel.getBuckName(),
                    aliOssConfigModel.getOssEndPort(), aliOssConfigModel.getRoot());
            OSS client = new OSSClientBuilder().build(this.aliOssConfigModel.getOssEndPort(),
                    this.aliOssConfigModel.getAppKey(), this.aliOssConfigModel.getAppSecret());
            String objectKey;

            if (!StringUtil.isNullOrEmpty(catalog)) {
                fileUrl += catalog + "/" + fileName;
                objectKey = this.aliOssConfigModel.getRoot() + "/" + catalog + "/" + fileName;
            } else {
                fileUrl += fileName;
                objectKey = this.aliOssConfigModel.getRoot() + "/" + fileName;

            }
            client.putObject(this.aliOssConfigModel.getBuckName(), objectKey, inputStream);
            client.shutdown();
            LOGGER.info("文件上传成功");
            return BaseResult.ok(fileUrl);

        } catch (OSSException e) {
            LOGGER.error(S1, e.getErrorMessage());
            return BaseResult.error(e.getErrorMessage());
        } catch (ClientException e) {
            LOGGER.error(S1, e.getErrorMessage());
            return BaseResult.error(e.getErrorMessage());
        }
    }

    @Override
    public BaseResult uploadBase64(String base64, String fileName) {
        return uploadBase64(base64, null, fileName);
    }

    @Override
    public BaseResult uploadBase64(String base64, String catalog, String fileName) {
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] bytes = decoder.decode(base64);
        InputStream inputStream = new ByteArrayInputStream(bytes);
        return BaseResult.ok(upload(inputStream, catalog, fileName));
    }

    @Override
    public BaseResult removeFile(String fileName) {
        return removeFiles(Arrays.asList(fileName));
    }

    @Override
    public BaseResult removeFiles(List<String> fileNames) {
        try {
            OSS client = new OSSClientBuilder().build(this.aliOssConfigModel.getOssEndPort(),
                    this.aliOssConfigModel.getAppKey(), this.aliOssConfigModel.getAppSecret());
            List<String> fileObjectNames = new ArrayList<>();
            String fileUrlPrefix = String.format("http://%s.%s/%s/", aliOssConfigModel.getBuckName(),
                    aliOssConfigModel.getOssEndPort(), aliOssConfigModel.getRoot());
            for (String fileName : fileNames) {
                String fileKey = fileName.replace(fileUrlPrefix, "");
                fileKey = this.aliOssConfigModel.getRoot() + "/" + fileKey;
                fileObjectNames.add(fileKey);
            }
            DeleteObjectsResult deleteObjectsResult = client.deleteObjects(
                    new DeleteObjectsRequest(this.aliOssConfigModel.getBuckName()).withKeys(fileObjectNames));
            deleteObjectsResult.getDeletedObjects();
            client.shutdown();
            LOGGER.info("文件刪除成功");
            return BaseResult.ok(null);
        } catch (OSSException e) {
            LOGGER.error(S1, e.getErrorMessage());
            return BaseResult.error(e.getErrorMessage());
        } catch (ClientException e) {
            LOGGER.error(S1, e.getErrorMessage());
            return BaseResult.error(e.getErrorMessage());
        }
    }

}
